diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt
index 438101ce1..da3469fc7 100644
--- a/sdrbase/CMakeLists.txt
+++ b/sdrbase/CMakeLists.txt
@@ -62,6 +62,7 @@ set(sdrbase_SOURCES
util/CRC64.cpp
util/db.cpp
+ util/fixedtraits.cpp
util/message.cpp
util/messagequeue.cpp
util/prettyprint.cpp
@@ -168,6 +169,7 @@ set(sdrbase_HEADERS
util/db.h
util/doublebuffer.h
util/export.h
+ util/fixedtraits.h
util/message.h
util/messagequeue.h
util/movingaverage.h
diff --git a/sdrbase/util/fixed.h b/sdrbase/util/fixed.h
new file mode 100644
index 000000000..582c5e05d
--- /dev/null
+++ b/sdrbase/util/fixed.h
@@ -0,0 +1,1983 @@
+///////////////////////////////////////////////////////////////////////////////////
+// (C) Copyright 2007 Anthony Williams //
+// //
+// Distributed under the Boost Software License, Version 1.0. //
+// See: http://www.boost.org/LICENSE_1_0.txt) //
+// //
+// Copyright (C) 2018 Edouard Griffiths, F4EXB //
+// //
+// Modified as fully templatized class with variable size and type internal //
+// representation //
+// //
+// 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 as version 3 of the License, or //
+// //
+// 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 V3 for more details. //
+// //
+// You should have received a copy of the GNU General Public License //
+// along with this program. If not, see . //
+///////////////////////////////////////////////////////////////////////////////////
+
+#ifndef SDRBASE_UTIL_FIXED_H_
+#define SDRBASE_UTIL_FIXED_H_
+
+#include
+#include
+#include
+
+#include "fixedtraits.h"
+
+// Internally 1 is 2^28. 28 is the highest power of two that can represent 9.99999... safely on 64 bits internally
+
+unsigned const fixed_resolution_shift=28;
+int64_t const fixed_resolution=1LL<
+class Fixed
+{
+private:
+ IntType m_nVal;
+
+public:
+
+ struct internal
+ {};
+
+ Fixed():
+ m_nVal(0)
+ {}
+
+ Fixed(internal, IntType nVal):
+ m_nVal(nVal)
+ {}
+ Fixed(int64_t nVal):
+ m_nVal(nVal << FixedTraits::fixed_resolution_shift)
+ {}
+
+ Fixed(int nVal):
+ m_nVal(int64_t(nVal) << FixedTraits::fixed_resolution_shift)
+ {}
+
+ Fixed(short nVal):
+ m_nVal(int64_t(nVal) << FixedTraits::fixed_resolution_shift)
+ {}
+
+ Fixed(uint64_t nVal):
+ m_nVal(nVal << FixedTraits::fixed_resolution_shift)
+ {}
+
+ Fixed(unsigned int nVal):
+ m_nVal(int64_t(nVal) << FixedTraits::fixed_resolution_shift)
+ {}
+ Fixed(unsigned short nVal):
+ m_nVal(int64_t(nVal) << FixedTraits::fixed_resolution_shift)
+ {}
+ Fixed(double nVal):
+ m_nVal(static_cast(nVal*static_cast(FixedTraits::fixed_resolution)))
+ {}
+ Fixed(float nVal):
+ m_nVal(static_cast(nVal*static_cast(FixedTraits::fixed_resolution)))
+ {}
+
+ template
+ Fixed& operator=(T other)
+ {
+ m_nVal = Fixed(other).m_nVal;
+ return *this;
+ }
+
+ Fixed& operator=(Fixed const& other)
+ {
+ m_nVal = other.m_nVal;
+ return *this;
+ }
+
+ friend bool operator==(Fixed const& lhs,Fixed const& rhs)
+ {
+ return lhs.m_nVal == rhs.m_nVal;
+ }
+
+ friend bool operator!=(Fixed const& lhs,Fixed const& rhs)
+ {
+ return lhs.m_nVal != rhs.m_nVal;
+ }
+
+ friend bool operator<(Fixed const& lhs,Fixed const& rhs)
+ {
+ return lhs.m_nVal < rhs.m_nVal;
+ }
+
+ friend bool operator>(Fixed const& lhs,Fixed const& rhs)
+ {
+ return lhs.m_nVal > rhs.m_nVal;
+ }
+
+ friend bool operator<=(Fixed const& lhs,Fixed const& rhs)
+ {
+ return lhs.m_nVal <= rhs.m_nVal;
+ }
+
+ friend bool operator>=(Fixed const& lhs,Fixed const& rhs)
+ {
+ return lhs.m_nVal >= rhs.m_nVal;
+ }
+
+ operator bool() const
+ {
+ return m_nVal?true:false;
+ }
+
+ inline operator double() const
+ {
+ return as_double();
+ }
+
+ int64_t as_internal() const
+ {
+ return m_nVal;
+ }
+
+ float as_float() const
+ {
+ return m_nVal/(float)fixed_resolution;
+ }
+
+ double as_double() const
+ {
+ return m_nVal/(double)fixed_resolution;
+ }
+
+ int64_t as_long() const
+ {
+ return (int64_t)(m_nVal/fixed_resolution);
+ }
+ int64_t as_int64() const
+ {
+ return m_nVal/fixed_resolution;
+ }
+
+ int as_int() const
+ {
+ return (int)(m_nVal/fixed_resolution);
+ }
+
+ uint64_t as_unsigned_long() const
+ {
+ return (uint64_t)(m_nVal/fixed_resolution);
+ }
+ uint64_t as_unsigned_int64() const
+ {
+ return (uint64_t)m_nVal/fixed_resolution;
+ }
+
+ unsigned int as_unsigned_int() const
+ {
+ return (unsigned int)(m_nVal/fixed_resolution);
+ }
+
+ short as_short() const
+ {
+ return (short)(m_nVal/fixed_resolution);
+ }
+
+ unsigned short as_unsigned_short() const
+ {
+ return (unsigned short)(m_nVal/fixed_resolution);
+ }
+
+ Fixed operator++()
+ {
+ m_nVal += fixed_resolution;
+ return *this;
+ }
+
+ Fixed operator--()
+ {
+ m_nVal -= fixed_resolution;
+ return *this;
+ }
+
+ Fixed floor() const;
+ Fixed ceil() const;
+ Fixed sqrt() const;
+ Fixed exp() const;
+ Fixed log() const;
+ Fixed& operator%=(Fixed const& other);
+ Fixed& operator*=(Fixed const& val);
+ Fixed& operator/=(Fixed const& val);
+
+ Fixed& operator-=(Fixed const& val)
+ {
+ m_nVal -= val.m_nVal;
+ return *this;
+ }
+
+ Fixed& operator+=(Fixed const& val)
+ {
+ m_nVal += val.m_nVal;
+ return *this;
+ }
+
+ Fixed& operator*=(double val)
+ {
+ return (*this)*=Fixed(val);
+ }
+
+ Fixed& operator*=(float val)
+ {
+ return (*this)*=Fixed(val);
+ }
+
+ Fixed& operator*=(int64_t val)
+ {
+ m_nVal*=val;
+ return *this;
+ }
+
+ Fixed& operator*=(int val)
+ {
+ m_nVal*=val;
+ return *this;
+ }
+
+ Fixed& operator*=(short val)
+ {
+ m_nVal*=val;
+ return *this;
+ }
+
+ Fixed& operator*=(char val)
+ {
+ m_nVal*=val;
+ return *this;
+ }
+
+ Fixed& operator*=(uint64_t val)
+ {
+ m_nVal*=val;
+ return *this;
+ }
+
+ Fixed& operator*=(unsigned int val)
+ {
+ m_nVal*=val;
+ return *this;
+ }
+
+ Fixed& operator*=(unsigned short val)
+ {
+ m_nVal*=val;
+ return *this;
+ }
+
+ Fixed& operator*=(unsigned char val)
+ {
+ m_nVal*=val;
+ return *this;
+ }
+
+ Fixed& operator/=(double val)
+ {
+ return (*this)/=Fixed(val);
+ }
+
+ Fixed& operator/=(float val)
+ {
+ return (*this)/=Fixed(val);
+ }
+
+ Fixed& operator/=(int64_t val)
+ {
+ m_nVal/=val;
+ return *this;
+ }
+
+ Fixed& operator/=(int val)
+ {
+ m_nVal/=val;
+ return *this;
+ }
+
+ Fixed& operator/=(short val)
+ {
+ m_nVal/=val;
+ return *this;
+ }
+
+ Fixed& operator/=(char val)
+ {
+ m_nVal/=val;
+ return *this;
+ }
+
+ Fixed& operator/=(uint64_t val)
+ {
+ m_nVal/=val;
+ return *this;
+ }
+
+ Fixed& operator/=(unsigned int val)
+ {
+ m_nVal/=val;
+ return *this;
+ }
+
+ Fixed& operator/=(unsigned short val)
+ {
+ m_nVal/=val;
+ return *this;
+ }
+
+ Fixed& operator/=(unsigned char val)
+ {
+ m_nVal/=val;
+ return *this;
+ }
+
+ bool operator!() const
+ {
+ return m_nVal==0;
+ }
+
+ Fixed modf(Fixed* integral_part) const;
+ Fixed atan() const;
+
+ static void sin_cos(Fixed const& theta,Fixed* s,Fixed*c);
+ static void to_polar(Fixed const& x,Fixed const& y,Fixed* r,Fixed*theta);
+
+ Fixed sin() const;
+ Fixed cos() const;
+ Fixed tan() const;
+ Fixed operator-() const;
+ Fixed abs() const;
+};
+
+/* why always as double ?
+inline std::ostream& operator<<(std::ostream& os,fixed const& value)
+{
+ return os<
+inline Fixed operator-(double a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+
+template
+inline Fixed operator-(float a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(uint64_t a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(int64_t a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(unsigned a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(int a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(unsigned short a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(short a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(unsigned char a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(char a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, double b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, float b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a,uint64_t b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, int64_t b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, unsigned b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, int b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, unsigned short b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, short b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, unsigned char b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, char b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator-(Fixed const& a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp -= b;
+}
+
+template
+inline Fixed operator%(double a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(float a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(uint64_t a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(int64_t a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(unsigned a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(int a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(unsigned short a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(short a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(unsigned char a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(char a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a,double b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, float b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, uint64_t b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, int64_t b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, unsigned b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, int b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, unsigned short b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, short b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, unsigned char b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, char b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator%(Fixed const& a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp %= b;
+}
+
+template
+inline Fixed operator+(double a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(float a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(uint64_t a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(int64_t a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(unsigned a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(int a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(unsigned short a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(short a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(unsigned char a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(char a, Fixed const& b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(Fixed const& a, double b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(Fixed const& a, float b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(Fixed const& a, uint64_t b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(Fixed const& a, int64_t b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(Fixed const& a, unsigned b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(Fixed const& a, int b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(Fixed const& a, unsigned short b)
+{
+ Fixed temp(a);
+ return temp += b;
+}
+
+template
+inline Fixed operator+(Fixed